﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Net;

namespace HashFoo.Core
{
    /// <summary>
    /// The result of a successful web request.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class WebResult<T> : IDisposable
    {
        HttpWebResponse _response;

        /// <summary>
        /// Creates a new <see cref="WebResult{T}"/> based on a <see cref="HttpWebResponse"/>.
        /// </summary>
        /// <param name="response"></param>
        protected WebResult(HttpWebResponse response)
        {
            Details = new WebResultDetails(response);
            _response = response;
        }

        /// <summary>
        /// The consumable data returned in the response.
        /// </summary>
        public T Data { get; protected set; }

        /// <summary>
        /// The response meta data details.
        /// </summary>
        public WebResultDetails Details { get; private set; }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public virtual void Dispose()
        {
            if (_response == null) return;

            _response.Dispose();
            _response = null;
        }

        /// <summary>
        /// Do cleanup before the response object is cleaned up.
        /// </summary>
        protected virtual void BeforeResponseDisposed()
        {

        }
    }

    /// <summary>
    /// Holds meta data about a web result (like status codes, content type, etc).
    /// </summary>
    public class WebResultDetails
    {
        /// <summary>
        /// The status code of the response.
        /// </summary>
        public HttpStatusCode StatusCode { get; set; }

        /// <summary>
        /// The content length of the response.
        /// </summary>
        public long ContentLength { get; set; }

        /// <summary>
        /// The content type of the response.
        /// </summary>
        public string ContentType { get; set; }

        /// <summary>
        /// Allows for the <c>WebResultDetail</c> to be created through property setters.
        /// </summary>
        public WebResultDetails()
        {

        }

        /// <summary>
        /// Create the meta data from a response.
        /// </summary>
        /// <param name="response"></param>
        public WebResultDetails(HttpWebResponse response)
        {
            StatusCode = response.StatusCode;
            ContentLength = response.ContentLength;
            ContentType = response.ContentType;
        }
    }
}